#include <allegro5\allegro.h>
#include <allegro5\allegro_font.h>
#include <allegro5\allegro_ttf.h>
#include <allegro5\allegro_native_dialog.h>
#include <allegro5\allegro_primitives.h>
#include <allegro5\allegro_image.h>
#include <math.h>
#include "sw_game_state_skateboard.h"
#include "sw_game_state_menu.h"
#include "sw_input_manager.h"
#include "globals.h"

sw_game_state_skateboard::sw_game_state_skateboard() {
	resting_count = 0;
	resting = false;

	font = al_load_font("fonts/arial.ttf", 16, 0);

	radius = 30;
	penis_height = 80;
	enemy_height = 35;
	enemy_dx = 2;
	enemy_width = 40;
	ground_y = global_screen_height - 50;
	penis_y = ground_y-penis_height;
	grav = 0.4;
	wheelradius = 5;
	wheelseparation_2 = 20;
	angle_arms = asin(0.3);
	arm_length = 50;

	penis_mass = 5;
	head_mass = 1;
	stick_length = 200;
	
	high_score = 0;
	high_enemy_score = 0;

	reset();
}

sw_game_state_skateboard::~sw_game_state_skateboard() {
	al_destroy_font(font);
}

void sw_game_state_skateboard::draw_on_screen() {
	int width = global_screen_width;
	int height = global_screen_height;
	al_draw_textf(font, al_map_rgb(255, 255, 255), 10, ground_y+10, ALLEGRO_ALIGN_LEFT,
		  "Score: %d", cur_enemy_score);
	al_draw_textf(font, al_map_rgb(255, 255, 255), width/2+10, ground_y+10, ALLEGRO_ALIGN_LEFT,
		  "High Score: %d", high_enemy_score);
	al_draw_line(0, ground_y+2, width, ground_y+2, al_map_rgb(255, 255, 0), 1);

	double head_cx = penis_x + stick_length*cos(theta);
	double head_cy = penis_y - stick_length*sin(theta);
	double eyeradius = radius/5;
	double righteye_cx = head_cx + radius*sin(theta)/2;
	double lefteye_cx = head_cx - radius*sin(theta)/2;
	double righteye_cy = head_cy + radius*cos(theta)/2;
	double lefteye_cy = head_cy - radius*cos(theta)/2;
	double rightsmile_x = lefteye_cx - radius/2*cos(theta);
	double leftsmile_x = righteye_cx - radius/2*cos(theta);
	double rightsmile_y = lefteye_cy + radius/2*sin(theta);
	double leftsmile_y = righteye_cy + radius/2*sin(theta);
	double neck_x = head_cx - radius*cos(theta);
	double neck_y = head_cy + radius*sin(theta);
	double rightarm_x = neck_x - cos(theta-angle_arms)*arm_length;
	double leftarm_x = neck_x - cos(theta+angle_arms)*arm_length;
	double rightarm_y = neck_y + sin(theta-angle_arms)*arm_length;
	double leftarm_y = neck_y + sin(theta+angle_arms)*arm_length;
	
	// legs
	al_draw_line(penis_x, penis_y, 
		penis_x+wheelseparation_2, penis_y+penis_height-2*wheelradius, 
		al_map_rgb(0, 0, 255), 2);
	al_draw_line(penis_x, penis_y, 
		penis_x-wheelseparation_2, penis_y+penis_height-2*wheelradius, 
		al_map_rgb(0, 0, 255), 2);

	// board
	al_draw_line(penis_x-wheelseparation_2-wheelradius, ground_y-2*wheelradius, 
		penis_x+wheelseparation_2+wheelradius, ground_y-2*wheelradius, 
		al_map_rgb(0, 255, 0), 2);
	al_draw_circle(penis_x-wheelseparation_2, ground_y-wheelradius, 5, al_map_rgb(0, 255, 0), 1);
	al_draw_circle(penis_x+wheelseparation_2, ground_y-wheelradius, 5, al_map_rgb(0, 255, 0), 1);

	// stick
	al_draw_line(penis_x, penis_y, head_cx, head_cy, al_map_rgb(0, 0, 255), 3);

	// arms
	al_draw_line(neck_x, neck_y, rightarm_x, rightarm_y, al_map_rgb(0, 0, 255), 3);
	al_draw_line(neck_x, neck_y, leftarm_x, leftarm_y, al_map_rgb(0, 0, 255), 3);

	// head
	al_draw_filled_circle(head_cx, head_cy, radius, al_map_rgb(0, 0, 255));
	al_draw_line(leftsmile_x, leftsmile_y, rightsmile_x, rightsmile_y, al_map_rgb(255, 255, 255), 2);
	al_draw_filled_circle(lefteye_cx, lefteye_cy, eyeradius, al_map_rgb(255, 255, 255));
	al_draw_filled_circle(righteye_cx, righteye_cy, eyeradius, al_map_rgb(255, 255, 255));

	// enemy
	al_draw_filled_rectangle(enemy_x-enemy_width/2, ground_y-enemy_height, enemy_x+enemy_width/2, ground_y, al_map_rgb(255, 0, 255));

}

void sw_game_state_skateboard::compute_timestep() {
	if (global_input_manager->times_pressed(ALLEGRO_KEY_SPACE)>0) {
		global_game_state->set_game_state_sub(new sw_game_state_menu());
		return;
	}

	if (resting) {
		resting_count ++;
		if (resting_count > global_frames_per_second / 2) {
			resting = false;
			resting_count = 0;
			reset();
		}
		return;
	}
	//jetpack force
	jetpackforce = 0;
	double jpf_r = 0;
	double jpf_l = 0;
	if (global_input_manager->pressed(ALLEGRO_KEY_RIGHT) || global_input_manager->times_pressed(ALLEGRO_KEY_RIGHT)>0) jpf_r += 3;
	if (global_input_manager->pressed(ALLEGRO_KEY_LEFT) || global_input_manager->times_pressed(ALLEGRO_KEY_LEFT)>0) jpf_l += 3;
	jetpackforce = jpf_r - jpf_l;
	//jetpackforce += inp->pressed(ALLEGRO_KEY_RIGHT)*3;
	//jetpackforce -= inp->pressed(ALLEGRO_KEY_LEFT)*3;

	double ddx = jetpackforce + head_mass*cos(theta)*(stick_length*dtheta*dtheta - grav*sin(theta));
	ddx /= (penis_mass + head_mass*cos(theta)*cos(theta));
	double ddtheta = grav*cos(theta)*(penis_mass*head_mass) - head_mass*stick_length*dtheta*dtheta*sin(theta)*cos(theta) - jetpackforce*sin(theta);
	ddtheta /= stick_length*(head_mass*sin(theta)*sin(theta) - penis_mass - head_mass);

	penis_dx += ddx;
	dtheta += ddtheta;
	penis_x += penis_dx;
	theta += dtheta;

	// enemy
	enemy_x += (enemy_dir ? enemy_dx : -enemy_dx);
	double dist = enemy_x - penis_x;
	dist = dist<0 ? -dist : dist;
	double contactdist = enemy_width/2 + wheelradius + wheelseparation_2;
	if (dist < contactdist) {
		cur_enemy_score ++;
		if (cur_enemy_score > high_enemy_score) {
			high_enemy_score = cur_enemy_score;
		}
		enemy_dir = !enemy_dir;
		if (enemy_dir) {
			enemy_x = -enemy_width;
		} else {
			enemy_x = global_screen_width + enemy_width;
		}
	}
	if (game_over()) {
		resting = true;
		resting_count = 0;
	}
}

bool sw_game_state_skateboard::game_over() {
	int width = global_screen_width;
	double head_cx = penis_x + stick_length*cos(theta);
	double head_cy = penis_y - stick_length*sin(theta);
	return (head_cx<=radius || head_cx>=width-radius || head_cy>=ground_y-radius);
}

void sw_game_state_skateboard::reset() {
	int width = global_screen_width;

	penis_x = width/2;
	enemy_x = -enemy_width;
	enemy_dir = true;
	theta = asin(1.0)+0.01;
	penis_dx = 0;
	dtheta = 0;
	jetpackforce = 0;

	cur_score = 0;
	cur_enemy_score = 0;
}